Passed
Push — master ( 5c5f2e...41aee4 )
by Plamen
01:24
created

table.js ➔ ... ➔ Draw   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 6
b 0
f 0
nc 3
nop 2
dl 0
loc 11
rs 10
1
var TableHelper = {
2
    BuildRequest: {
3
        Sort: function (rq, strDesc){
4
            function sortBySpan(span, i){
5
                var order = span.innerHTML;
6
                if(order.length === 1){
7
                    rq.colNo = i;
8
                    rq.colOrd = order === strDesc ? "desc" : "asc";
9
                }
10
                return rq.colNo === i;
11
            }
12
13
            var thTags = document.getElementById(rq.tableId)
14
                    .getElementsByTagName("thead")[0]
15
                    .getElementsByTagName("th");
16
            var length = thTags.length;
17
            for(var i = 0; i < length; i++){
18
                var link = thTags[i].getElementsByTagName("a")[0];
19
                if(link){
20
                    var span = link.getElementsByTagName("span")[0];
21
                    if(span && sortBySpan(span, i)){
22
                        break;
23
                    }
24
                }
25
            }
26
        },
27
    Filter: function (rq){
28
            function getFilterFieldsByTableID(tableID){
29
                var fields = {filterBy: null, filter: null};
30
                var filterDiv = getFilterDivByTableIDOrNull(tableID);
31
                if(filterDiv !== null){
32
                    setFilterBy(fields, filterDiv);
33
                    setFilterValue(fields, filterDiv);
34
                }
35
                return fields;
36
            }
37
            function getFilterDivByTableIDOrNull(tableID){
38
                var res = null;
39
                if(document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0){
40
                    for(var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++){
41
                        if(document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class") === "filter"){
42
                            return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
43
                        }
44
                    }
45
46
                }
47
                return res;
48
            }
49
            function setFilterBy(fields, filterDiv){
50
                var slctObj = filterDiv.getElementsByTagName("select")[0];
51
                if(slctObj && slctObj.options[slctObj.selectedIndex].value !== "all"){
52
                    fields.filterBy = slctObj.options[slctObj.selectedIndex].value;
53
                }
54
            }
55
            function setFilterValue(fields, filterDiv){
56
                var textObj = filterDiv.getElementsByTagName("input")[0];
57
                if(textObj && textObj.value && textObj.value.length !== 0){
58
                    fields.filter = encodeURIComponent(textObj.value.trim());
59
                }
60
            }
61
62
            var r = getFilterFieldsByTableID(rq.tableId);
63
            if(r.filter !== null){
64
                rq.filter = r.filter;
65
            }
66
            if(r.filterBy !== null){
67
                rq.filterBy = r.filterBy;
68
            }
69
        }
70
    },
71
    ColumnHover: function(tableContainer, index){
72
        var rows = document.getElementById(tableContainer).rows;
73
        var upto = rows.length - 1;
74
        if(typeof index === "undefined"){
75
            ColumnHoverRelease(rows, upto);
76
        } else {
77
            for(var i = 0; i < upto; i++){
78
                rows[i].cells[index].setAttribute("lang", "col-hover");
79
            }
80
        }
81
        function ColumnHoverRelease(rows, upto){
82
            for(var i = 0; i < upto; i++){
83
                for(var j = 0; j < rows[i].cells.length; j++){
84
                    if(rows[i].cells[j].lang){
85
                        rows[i].cells[j].removeAttribute("lang");
86
                    }
87
                }
88
            }
89
        };
90
    },
91
    Filter: {
92
        GetTableId: function(field){
93
            if(field.tagName.toLowerCase() !== "select"){
94
                return field.getAttribute("data-table-id");
95
            }
96
            var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
97
            return '' === f.value ? null : f.getAttribute("data-table-id");
98
        }
99
    },
100
    Init: {
101
        SetColumnsHoverEffect: function (tContainer, tableId){
102
            var tHcells = tContainer.rows[0].cells;
103
            for(var i = 0; i < tHcells.length; i++){
104
                if(tHcells[i].firstChild.tagName === "A"){
105
                    tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableId + "'," + i + ");");
106
                    tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableId + "');");
107
                }
108
            }
109
        }
110
    },
111
    GoPage: {
112
        GetNo: function(lnk, tableId){
113
            //check & serve pagination jump links
114
            var jumpDir = lnk.innerHTML.trim().substr(0, 1);
115
            if(jumpDir === "+" || jumpDir === "-"){
116
                var current = document.getElementById(tableId)
117
                                .querySelector("tfoot .paging .a").innerHTML;
118
                var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
119
                var jumpPage = (parseInt(current) + parseInt(jump));
120
                lnk.parentNode.setAttribute("data-page", jumpPage);
121
                lnk.style.transform = "none";
122
            }
123
            return lnk.parentNode.hasAttribute("data-page") ?
124
                    lnk.parentNode.getAttribute("data-page") :
125
                    lnk.innerHTML;
126
        }
127
    },
128
    LoadData: {
129
        SetVisability: function(tableContainer, flag){
130
            var tbl = document.getElementById(tableContainer);
131
            if(flag === true){
132
                tbl.style.filter = "none";
133
                tbl.style.opacity = "1";
134
                tbl.style.cursor = "auto";
135
            }else if(flag === false){
136
                tbl.style.filter = "blur(1px)";
137
                tbl.style.opacity = "0.8";
138
                tbl.style.cursor = "wait";
139
            }else{
140
                console.error("table error in the flag value");
141
            }
142
        }
143
    },
144
    
145
    IePrior: function(v){
146
        var rv = false;
147
        if(window.navigator.appName === 'Microsoft Internet Explorer'){
148
            var ua = window.navigator.userAgent;
149
            var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
150
            if(re.exec(ua) !== null){
151
                rv = parseFloat(RegExp.$1);
152
            }
153
            rv = rv < v ? true : false;
154
        }
155
        return rv;
156
    },
157
    GetParent: function(obj, objType){
158
        while(obj && obj.tagName !== objType.toUpperCase()){
159
            obj = obj.parentNode;
160
        }
161
        return obj;
162
    },
163
    ProcessPaginationLinks: function(tfoot){
164
        var pLinks = tfoot.querySelectorAll(".paging a");
165
        if(pLinks.length > 0){
166
            for(var j = 0; j < pLinks.length; j++){
167
                pLinks[j].setAttribute("href", "javascript:void(0);");
168
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
169
            }
170
        }
171
    },
172
    RequestToUrl: function(rq){
173
        var url = location.pathname + ".json" + location.search;
174
        if(typeof rq === "object"){
175
            var getUrlVarName = {
176
                colNo: "col", colOrd: "ord", filter: "filter",
177
                filterBy: "filter-by", pageNo: "pg", exportType: "export",
178
                tableId: "table-id"
179
            };
180
            var flagFirst = location.search.length < 1 ? true : false;
181
            for(var r in rq){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
182
                var clue = flagFirst === true ? "?" : "&";
183
                url += clue + getUrlVarName[r] + "=" + rq[r];
184
                flagFirst = false;
185
            }
186
        }
187
        return url;
188
    }
189
};
190
191
var TableHelperFilterGetTableId = function(field){
192
    if(field.tagName.toLowerCase() !== "select"){
193
        return field.getAttribute("data-table-id");
194
    }
195
    var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
196
    return '' === f.value ? null : f.getAttribute("data-table-id");
197
};
198
var TableHelperDraw_Section = function(tableContainer, dt, tSection){
199
    var section = tSection === "tfoot" ? "tfoot" : "tbody";
200
    var tSec = document.getElementById(tableContainer)
201
                .getElementsByTagName(section)[0];
202
    TableHelperDraw_SectionClear(tSec, TableHelper.IePrior(9));
203
    for(var i = 0; i < dt.length; i++){
204
        var row = dt[i];
205
        var tRow = document.createElement("tr");
206
        TableHelperDraw_SectionRow(row, tRow);
207
        tSec.appendChild(tRow);
208
        if(section === "tfoot"){
209
            TableHelper.ProcessPaginationLinks(tSec);
210
        }
211
    }
212
};
213
var TableHelperDraw_SectionClear = function(tSection, iePrior9){
214
    if(iePrior9){
215
        if(tSection.firstChild){
216
            while(tSection.firstChild){
217
                tSection.removeChild(tSection.firstChild);
218
            }
219
        }
220
    }else{
221
        tSection.innerHTML = "";
222
    }
223
};
224
var TableHelperDraw_SectionRow = function(row, tRow){
225
    for(var cell in row){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
226
        var tCell = document.createElement("td");
227
        if(typeof row[cell] === "string" || typeof row[cell] === "number"){
228
            tCell.innerHTML = row[cell];
229
        }else if(typeof row[cell] === "object"){
230
            TableHelperDraw_SectionRowCellFromObject(row, cell, tCell);
231
        }
232
        tRow.appendChild(tCell);
233
    }
234
};
235
var TableHelperDraw_SectionRowCellFromObject = function(row, cell, tCell){
236
    for(var attr in row[cell]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
237
        if(typeof row[cell][attr] === "string"){
238
            tCell.innerHTML = row[cell][attr];
239
        }else if(typeof row[cell][attr] === "object"){
240
            for(var v in row[cell][attr]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
241
                tCell.setAttribute(v, row[cell][attr][v]);
242
            }
243
        }
244
    }
245
};
246
247
//https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript
248
var TableSingleton = (function(){
249
    // Instance stores a reference to the Singleton
250
    var instance;
251
    function initInstance(){
252
        // Singleton
253
        // Private methods and variables
254
        function BuildRequest(rq, crntTableId, strDesc){
255
            rq.tableId = crntTableId;
256
            TableHelper.BuildRequest.Sort(rq, strDesc);
257
            TableHelper.BuildRequest.Filter(rq);
258
        };
259
        function Draw(tableContainer, d){
260
            TableHelperDraw_Section(tableContainer, d.body);
261
            TableHelperDraw_Section(tableContainer, d.footer, "tfoot");
262
            if(instance.rq !== null){
263
                var hover = document.getElementById(instance.rq.tableId)
264
                            .getElementsByTagName("th")[instance.rq.colNo].lang;
265
                if(hover){
266
                    instance.ColumnHover(tableContainer, instance.rq.colNo);
267
                }
268
            }
269
        }
270
        var tail = null;
271
        function LoadData(tableContainer, rq){
272
            if(tail!==null){ tail.abort();}
273
            TableHelper.LoadData.SetVisability(tableContainer, false);
274
            var xmlhttp = window.XMLHttpRequest ? 
275
                            new XMLHttpRequest() : /* code for IE7+, Firefox, Chrome, Opera, Safari */
276
                            new window.ActiveXObject("Microsoft.XMLHTTP");/*code for IE6, IE5 */
277
            xmlhttp.onreadystatechange = function(){
278
                if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
279
                    Draw(tableContainer, JSON.parse(xmlhttp.responseText));
280
                    TableHelper.LoadData.SetVisability(tableContainer, true);
281
                    instance.LoadEndCalback(tableContainer);
282
                }
283
            };
284
            xmlhttp.open("GET", RequestToUrl(rq), true);
285
            xmlhttp.send();
286
            tail = xmlhttp; //put at tail to can abort later any previous
287
        }
288
        function ReloadData(tableId){
289
            var request = {};
290
            BuildRequest(request, tableId, this.strDesc);
291
            LoadData(tableId, request);
292
        }
293
294
        var GoPageGetNo = TableHelper.GoPage.GetNo;
295
        var getParent = TableHelper.GetParent;
296
        var RequestToUrl = TableHelper.RequestToUrl;
297
298
        return {
299
            rq: null,
300
            strAsc: String.fromCharCode(9650), //&#9650;
301
            strDesc: String.fromCharCode(9660),//&#9660; 
302
            ColumnHover: TableHelper.ColumnHover, //function(tableContainer, index)
303
            Export: function(lnk, eType){
304
                var request = {};
305
                var crntTableId = getParent(lnk, "table").getAttribute("id");
306
                BuildRequest(request, crntTableId, this.strDesc);
307
                request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ?
308
                                        eType : 
309
                                        "csv";
310
                window.open(RequestToUrl(request));
311
                return false;
312
            },
313
            Filter: function(field){
314
                var crntTableId = TableHelper.Filter.GetTableId(field);
315
                if(crntTableId !== null){
316
                    var request = {};
317
                    var exRq = this.rq;
318
                    BuildRequest(request, crntTableId, this.strDesc);
319
                    if(exRq === null ||
320
                        request.filter !== exRq.filter ||
321
                        request.filterBy !== exRq.filterBy
322
                    ){
323
                        LoadData(crntTableId, request);
324
                    }
325
                }
326
            },
327
            GoPage: function(lnk){
328
                var request = {};
329
                var crntTableId = getParent(lnk, "table").getAttribute("id");
330
                BuildRequest(request, crntTableId, this.strDesc);
331
                request.pageNo = GoPageGetNo(lnk, crntTableId);
332
                LoadData(crntTableId, request);
333
                return false;
334
            },
335
            init: function (tableId){
336
                var tContainer = document.getElementById(tableId);
337
                if(!TableHelper.IePrior(9)){
338
                    TableHelper.Init.SetColumnsHoverEffect(tContainer, tableId);
339
                }
340
                var tfoot = tContainer.getElementsByTagName("tfoot")[0];
341
                TableHelper.ProcessPaginationLinks(tfoot);
342
            },
343
            LoadEndCalback: function(){},/*Allows override: function(tableId){if(tableId){...}}*/
344
            ReloadData: ReloadData,
345
            Sort: function(colNo, lnk){
346
                var request = {};
347
                var crntTableId = getParent(lnk, "table").getAttribute("id");
348
                BuildRequest(request, crntTableId, this.strDesc);
349
                if(Math.round(colNo) === request.colNo){
350
                    request.colOrd = (request.colOrd === "asc" ? "desc" : "asc");
351
                }else{
352
                    request.colNo = Math.round(colNo);
353
                    request.colOrd = "asc";
354
                }
355
                LoadData(crntTableId, request);
356
                /* Clear and add new sort arrow */
357
                var headSpans = getParent(lnk, "thead").getElementsByTagName("span");
358
                var length = headSpans.length;
359
                for(var i = 0; i < length; i++){
360
                    headSpans[i].innerHTML = "";
361
                }
362
                lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? this.strDesc : this.strAsc);
363
            }
364
        };
365
    }
366
    return {
367
        //Get the Singleton instance if one exists, or create one if it doesn't
368
        getInstance: function(){
369
            if(!instance){
370
                instance = initInstance();
371
            }
372
            return instance;
373
        }
374
    };
375
})();
376
var table = TableSingleton.getInstance();
377